package publish

import (
	"fmt"
	"gitee.com/fierce_wolf/go-fox-edge-common/commEntity"
	"gitee.com/fierce_wolf/go-fox-edge-common/commLogger"
	"gitee.com/fierce_wolf/go-fox-edge-common/commSql"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/String"
	"go-fox-edge-iot-fox-publish/component"
	"go-fox-edge-iot-fox-publish/remote"
	"strings"
)

type recordEntityPublisher struct {
}

func (e *recordEntityPublisher) publish(entityType string) {
	// 定义一个函数级的异常拦截，用来防止可能的代码BUG
	defer func() {
		if r := recover(); r != nil {
			commLogger.Console.Error(fmt.Sprintf("config() 捕获到异常:%v", r))
		}
	}()

	// 检查：是否到了执行的时间间隔
	ok, err := component.TimeIntervalService.TestLastTime(String.CamelName(entityType))
	if err != nil || !ok {
		return
	}

	entity, err := commEntity.NewEntity(entityType)
	if err != nil {
		return
	}

	// 注册数据库访问信息：后面它能够根据Entity的注册信息，获得数据库的相关访问信息
	commSql.Register(entityType)

	// 分批处理
	pageSize := 100
	for true {
		count, err := e.syncEntity(entityType, entity.TableName(), pageSize, 10*1000)
		if err != nil {
			break
		}

		if count != pageSize {
			break
		}
	}

}

func (e *recordEntityPublisher) syncEntity(entityType, tableName string, pageSize int, timeOut int64) (int, error) {
	// 查询数据库的最新ID
	entityList, err := commSql.Query(entityType, "SELECT * FROM "+tableName+" ORDER  BY id DESC LIMIT 1")
	if err != nil {
		return 0, err
	}
	if len(entityList) == 0 {
		return 0, nil
	}

	// 查询云端的时间戳
	timestamp, err := remote.RemoteCloud.QueryTimestamp(entityType, timeOut)
	if err != nil {
		return 0, err
	}

	// 进行比对，确认差额的数据
	localId := entityList[0].GetBaseEntity().Id
	remoteId := timestamp
	if localId <= remoteId {
		return 0, nil
	}

	// 查询数据
	entityList, err = commSql.Query(entityType, "SELECT * FROM "+tableName+" WHERE id > "+String.ToString(remoteId)+" ORDER  BY id ASC LIMIT "+String.ToString(pageSize))
	if err != nil {
		return 0, err
	}

	// 发布数据到云端
	dataMap := make(map[string]interface{})
	dataMap["insert"] = entityList

	// 推送数据到云端
	remote.RemoteCloud.PublishEntity(strings.ToLower(entityType), dataMap)
	return len(entityList), nil

}
